package com.yexiao.cofe.util;

import cn.hutool.core.util.StrUtil;
import com.yexiao.core.util.IDateUtil;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandlerRegistry;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;

public class MybatisUtil {
    public MybatisUtil() {
    }

    public static String getSQL(Invocation invocation) {
        try {
            Object[] args = invocation.getArgs();
            MappedStatement mappedStatement = (MappedStatement)args[0];
            Object parameter = null;
            if (args.length > 1) {
                parameter = args[1];
            }

            BoundSql boundSql = mappedStatement.getBoundSql(parameter);
            Configuration configuration = mappedStatement.getConfiguration();
            return getSql(configuration, boundSql);
        } catch (Exception var6) {
            return "";
        }
    }

    public static String getSql(Configuration configuration, BoundSql boundSql) {
        String sql = boundSql.getSql();
        return StrUtil.isEmpty(sql) ? "" : formatSql(sql, configuration, boundSql);
    }

    private static String formatSql(String sql, Configuration configuration, BoundSql boundSql) {
        sql = beautifySql(sql);
        Object parameterObject = boundSql.getParameterObject();
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
        List<String> parameters = new ArrayList();
        if (parameterMappings != null) {
            MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
            Iterator var8 = parameterMappings.iterator();

            while(var8.hasNext()) {
                ParameterMapping parameterMapping = (ParameterMapping)var8.next();
                if (parameterMapping.getMode() != ParameterMode.OUT) {
                    String propertyName = parameterMapping.getProperty();
                    Object value;
                    if (boundSql.hasAdditionalParameter(propertyName)) {
                        value = boundSql.getAdditionalParameter(propertyName);
                    } else if (parameterObject == null) {
                        value = null;
                    } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                        value = parameterObject;
                    } else {
                        value = metaObject == null ? null : metaObject.getValue(propertyName);
                    }

                    parameters.add(getParameterValue(value));
                }
            }
        }

        String value;
        for(Iterator var12 = parameters.iterator(); var12.hasNext(); sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(value))) {
            value = (String)var12.next();
        }

        return sql;
    }

    private static String getParameterValue(Object obj) {
        if (obj instanceof String) {
            return "'" + obj + "'";
        } else {
            String dateFormat;
            if (obj instanceof Date) {
                dateFormat = IDateUtil.format((Date)obj);
                return "'" + dateFormat + "'";
            } else if (obj instanceof LocalDateTime) {
                dateFormat = IDateUtil.format((LocalDateTime)obj, "yyyy-MM-dd HH:mm:ss");
                return "'" + dateFormat + "'";
            } else {
                return obj != null ? obj.toString() : "";
            }
        }
    }

    private static String beautifySql(String sql) {
        sql = sql.replaceAll("[\\s\n ]+", " ");
        return sql;
    }
}
